var labelType, useGradients, nativeTextSupport, animate;
(function() {
    var ua = navigator.userAgent,
    iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i),
    typeOfCanvas = typeof HTMLCanvasElement,
    nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
    textSupport = nativeCanvasSupport 
    && (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
    //I'm setting this based on the fact that ExCanvas provides text support for IE
    //and that as of today iPhone/iPad current text support is lame
    labelType = (!nativeCanvasSupport || (textSupport && !iStuff))? 'Native' : 'HTML';
    nativeTextSupport = labelType == 'Native';
    useGradients = nativeCanvasSupport;
    animate = !(iStuff || !nativeCanvasSupport);
})();

jQuery(document).ready(function() {
    ////////////////////////
    //Variable definition///
    ////////////////////////
    //Style variables
    var topColor = '#000033';//top node color
    var indexColor = '#003399';//index node color
    var expandedColor = '#336666';//expadnded node color
    var surgeryColor = '#009966';//surgery node color
    var addedColor = '#FF9933';//added node color
    var windowHeight = 0;// The window height
    var windowWidth = 0;// The window width  
    var contentHeight = 0;// The content height  
    var leftWidth = 0;//
    //Functional variables
    var indexNodesArray=new Array();
    var expandedNodesArray=new Array();
    var surgeryNodesArray=new Array();
    var spaceTree;//Reference the spaceTree
    var queryString;//Reference to queryString
    ////////////////////////
    ////jQuery selectors////
    ////////////////////////
    var leftPanel = jQuery("#left");  
    var rightPanel= jQuery("#right");  
    var toggler = jQuery("#toggler");  
    var tags = jQuery("#tags");  
    var tree = jQuery("#tree");  
    var queryInput = jQuery('#queryForm\\:queryString');
    ////////////////////////
    ///////Functions////////
    ////////////////////////
    //Calculte window dimensions
    function calculateDimensions(){  
        windowHeight = document.documentElement.clientHeight;
        windowWidth = document.documentElement.clientWidth;
        contentHeight = (windowHeight - 63 - 20)  +"px";  
    }  
    //Resize the panels
    function resizePanels(){  
        //Set the widths
        rightPanel.css("width",windowWidth-leftWidth);
        jQuery("#resultsTitle").css("width",windowWidth-leftWidth-20);
        //Set the heights
        tags.css("height", contentHeight);
        tree.css("height", contentHeight);
        toggler.css("height", contentHeight);  
        jQuery("#browseContent").css("height",contentHeight);
        jQuery("#resultsList").css("max-height",contentHeight);
        jQuery("#infovis").css("height",contentHeight);
        
    }  
    //Show tags and hide tree
    function showTags(){  
        tags.show();  
        tree.hide();
        toggler.hide();
    }  
    //Show tree and hide tags
    function showTree(){  
        tags.hide();  
        tree.show();
        toggler.show();
    } 
    function initVisualization(){
        //Create a new ST instance
        spaceTree = new $jit.ST({
            //id of viz container element
            injectInto: 'infovis',
            //set duration for the animation
            duration: 200,
            //set animation transition type
            transition: $jit.Trans.Quart.easeInOut,
            //set distance between node and its children
            levelDistance: 10,
            //enable panning
            Navigation: {
                enable:true,
                panning:false
            },
            //set node and edge styles
            //set overridable=true for styling individual
            //nodes or edges
            Node: {
                height: 25,
                width: 90,
                type: 'rectangle',
                color: '#aaa',
                overridable: true
            },
            Edge: {
                type: 'bezier',
                overridable: true
            },
            //Add tooltips  
            Tips: {  
                enable: true,  
                offsetX: 10,
                offsetY: 10,
                onShow: function(tip, node) {  
                    var data = node.data;  
                    var html = "<div class=\"tip-content\">"
                    html += "<div class=\"tip-title\">" + data.term;
                    html += "</div><div style=\"padding: 0 2px;\"><b class=\"tip-label\">Category:  </b>" + data.category;
                    html += "</div><div style=\"float: left; padding: 0 2px;\"><b class=\"tip-label\">ConceptId:</b>" + data.conceptId;
                    html += "<br/><b class=\"tip-label\">DescriptorId:</b>" + data.descriptorId;
                    html += "</div><div style=\"float: left; padding: 0 2px;\"><b class=\"tip-label\">Total Occurrences:</b>" + 10;
                    html += "<br/><b class=\"tip-label\">Document Occurrences:</b>" + 3 + "</div></div>";
                    tip.innerHTML = html;  
                //jQuery.('.descriptorId').css(Color.red)
                }  
            }, 
            //This method is called on DOM label creation.
            //Use this method to add event handlers and styles to
            //your node.
            onCreateLabel: function(label, node){
                label.id = node.id;            
                label.innerHTML = node.name;
                label.onclick = function(){                
                    spaceTree.onClick(node.id);
                    if(node.data.nodeType=="S"){
                        node.data.nodeType="A";
                        addedCount++;
                        surgeryCount--;
                        renderDynamicLabelCounts();
                        queryInput.data(node.data.descriptorId,"+"+node.data.term);
                        renderQueryString();
                    }
                    else  if(node.data.nodeType=="A"){
                        addedCount--;
                        surgeryCount++;
                        renderDynamicLabelCounts();
                        node.data.nodeType="S";
                        queryInput.data(node.data.descriptorId,"-"+node.data.term);
                        renderQueryString();
                    }
                    else {
                        renderResults(node.data.conceptId);
                    }
                };
                //set label styles
                var style = label.style;
                style.width = 90 + 'px';
                style.height = 24 + 'px';            
                style.cursor = 'pointer';
                style.color = '#FFFFFF';
                style.fontSize = '0.8em';
                style.textAlign= 'center';
                style.paddingTop = '1px';
                style.overflow = 'hidden';
            },
            //This method is called right before plotting
            //a node. It's useful for changing an individual node
            //style properties before plotting it.
            //The data properties prefixed with a dollar
            //sign will override the global node style properties.
            onBeforePlotNode: function(node){
                if(node.data.nodeType=="I"){
                    node.data.$color = indexColor;
                }
                else if(node.data.nodeType=="E"){
                    node.data.$color = expandedColor;
                }
                else if(node.data.nodeType=="S"){
                    node.data.$color = surgeryColor;
                }
                else if(node.data.nodeType=="A"){
                    node.data.$color = addedColor;
                }
                else{
                    node.data.$color = topColor;
                }
            },
            //This method is called right before plotting
            //an edge. It's useful for changing an individual edge
            //style properties before plotting it.
            //Edge data proprties prefixed with a dollar sign will
            //override the Edge global style properties.
            onBeforePlotLine: function(adj){
                if (adj.nodeFrom.selected && adj.nodeTo.selected) {
                    adj.data.$color = "#000033";
                    adj.data.$lineWidth = 3;
                }
                else {
                    delete adj.data.$color;
                    delete adj.data.$lineWidth;
                }
            }
        
        });
        var subHierarchyJson = jQuery.parseJSON(jQuery('#infovisData').text());
        //load json data
        spaceTree.loadJSON(subHierarchyJson);
        //compute node positions and layout
        spaceTree.compute();
        //emulate a click on the root node.
        spaceTree.onClick(spaceTree.root);
    }
    //Render the query string showing the added concepts
    function renderQueryString(){
        var tempQueryString="";
        jQuery.each( queryInput.data(),function(key, value) {
            if(value.charAt(0)=="+"){
                tempQueryString  += "KS:"+key+":"+value.substr(1)+"+";
            }
        });
        if(tempQueryString.length>0){
            queryInput.val(queryString+" | "+tempQueryString);
        }else{
            queryInput.val(queryString);
        }
    }
    //Render the results
    function renderResults(nodeId){
        var documentMap = spaceTree.graph.getNode(nodeId).data.documentMap;
        var documentMapTokens= documentMap.split(",");
        var resultsCount = 0;
        var documentCount  = 0;
        var tokenCount = 0;
        jQuery('.singleResult').each(function(index) {
            if(documentCount==documentMapTokens[tokenCount]){
                tokenCount++;
                documentCount = 0;
            }
            if(tokenCount%2==0){
                this.style.display = "block";
                resultsCount++;
            }else{
                this.style.display = "none";
            }
            documentCount++;
        });
        jQuery('#numResults').text(resultsCount+" ")  
    }
    //Build the tag clouds
    function buildTagCloud(){
        var queryTags = jQuery("#queryTags");
        var resultsTags = jQuery("#resultsTags");
        var surgeryTags = jQuery("#surgeryTags");
        spaceTree.graph.eachNode(function(node) { 
            var randomnumber=Math.floor(Math.random()*20)
            if(node.data.nodeType=="I"){
                indexNodesArray.push(node.id);
                queryTags.append("<a id=\"tag"+node.id+"\" class=\"tagLabel\" href=\"#\" rel=\""+randomnumber+"\">"+node.data.term+"</a>");
            }
            if(node.data.nodeType=="E"){
                expandedNodesArray.push(node.id);
                resultsTags.append("<a id=\"tag"+node.id+"\" class=\"tagLabel\" href=\"#\" rel=\""+randomnumber+"\">"+node.data.term+"</a>");
            }
            if(node.data.nodeType=="S"){
                surgeryNodesArray.push(node.id);
                queryTags.append("<a id=\"tag"+node.id+"\" class=\"tagLabel\" href=\"#\" rel=\""+randomnumber+"\">"+node.data.term+"</a>");
            }
        });
        jQuery(".tagLabel").click(function(){
            var tagId = this.id.substr(3);
            spaceTree.onClick(tagId);
            renderResults(tagId);
        //            showTree();
        });
        jQuery.fn.tagcloud.defaults = {
            size: {
                start: 8, 
                end: 20, 
                unit: 'pt'
            },
            color: {
                start: '#3333FF', 
                end: '#000033'
            }
        };
        jQuery("#queryTags a").tagcloud();
        jQuery("#resultsTags a").tagcloud();
        jQuery("#surgeryTags a").tagcloud();
    }
    ////////////////////////
    //Init data structures//
    ////////////////////////
    leftWidth = leftPanel.width()+1;//
    queryString = queryInput.val();
    ////////////////////////
    ///////Add handlers/////
    ////////////////////////
    queryInput.click(function() {
        queryInput.val("");
    });
    $(window).resize(function(){  
        calculateDimensions();  
        resizePanels();  
    }); 
    toggler.hover(showTags,null);  
    tags.hover(null, showTree)
    ////////////////////////
    /////Init application///
    ////////////////////////
    calculateDimensions();  
    resizePanels(); 
    showTree();  
    initVisualization();
    buildTagCloud();
});